import * as fs from 'fs'
import * as path from 'path'

import { HttpException, Injectable } from '@nestjs/common'

import { uploadConfig, uploadConfigMessage } from '@/config/upload.config'

@Injectable()
export class UploadService {
  private readonly uploadDir = uploadConfig.uploadDir

  constructor() {
    if (!fs.existsSync(this.uploadDir)) {
      fs.mkdirSync(this.uploadDir, { recursive: true })
    }
  }

  async uploadFile(file: Express.Multer.File) {
    try {
      this.validateFile(file)
      const fileInfo = await this.saveFile(file)
      return fileInfo
    }
    catch (error) {
      throw new HttpException(error.message || '文件上传失败', 400)
    }
  }

  async uploadFiles(files: Express.Multer.File[]) {
    try {
      if (files.length > uploadConfig.maxFiles) {
        throw new HttpException(`一次最多上传${uploadConfig.maxFiles}个文件`, 400)
      }

      files.forEach(file => this.validateFile(file))

      const uploadedFiles = await Promise.all(files.map(file => this.saveFile(file)))

      return {
        successCount: uploadedFiles.length,
        files: uploadedFiles,
      }
    }
    catch (error) {
      throw new HttpException(error.message || '文件上传失败', 400)
    }
  }

  private validateFile(file: Express.Multer.File) {
    console.log(file.mimetype)
    if (file.size > uploadConfig.maxFileSize) {
      throw new HttpException(uploadConfigMessage.fileSizeErrorMessage, 422)
    }

    if (!uploadConfig.allowedMimeTypes.includes(file.mimetype)) {
      throw new HttpException(`${uploadConfigMessage.fileTypeErrorMessage}:${file.mimetype}`, 422)
    }
  }

  private async saveFile(file: Express.Multer.File) {
    const uniqueSuffix = `${Date.now()}-${Math.round(Math.random() * 1e9)}`

    // 原文件名的基础部分（不含路径）
    // const ext = path.extname(file.originalname) // 获取扩展名，例如 ".png"
    // const baseName = path.basename(file.originalname, ext)

    // 把中文和特殊字符替换为下划线，只保留字母数字 - _
    // const safeBaseName = baseName.replace(/[^\w-]/g, '_')
    // 最终文件名
    // const filename = `${uniqueSuffix}-${baseName}-${ext}`;
    const filename = `${uniqueSuffix}-${file.originalname}`

    // 保存路径（磁盘上的真实路径）
    const filepath = path.join(this.uploadDir, filename)
    fs.writeFileSync(filepath, file.buffer)

    // 返回值
    return {
      originalname: file.originalname,
      filename,
      filepath: `/static/${filename}`,
      mimetype: file.mimetype,
      size: file.size,
    }
  }
}
